# 回测引擎与性能 本章从**使用与结果**角度说明 qteasy 的回测引擎如何工作,以及**性能与向量化**的实现方式,便于用户理解回测速度与正确性的来源。更底层的架构说明见《架构与设计》中的 [回测引擎与性能(设计视角)](../design/07-backtest-engine-and-performance.md)。 ## 1. 回测引擎概览 回测入口与流程已在 [回测概览](1.%20overview.md) 与 [如何运行回测](2.%20run_backtest.md) 中说明:通过 `qt.run(op, mode=1, ...)` 进入回测模式,内部按 **group_timing_table** 的每个时间步运行策略、解析信号并模拟成交。 与“逐 bar 事件驱动”或“全时间轴一次性矩阵运算”不同,qteasy 采用 **时间维顺序步进、单步内标的维向量化** 的方式: - **时间维**:按真实交易节奏顺序执行每个时间步,以正确维护现金、持仓、交割队列(如 T+1)等状态。 - **标的维**:在每个时间步内,对资产池中所有标的的买卖量、费用、持仓更新等做 **向量化计算**(NumPy 数组 + Numba 加速),单步效率高。 这样既保证了与实盘一致的状态与规则,又避免了纯事件驱动下的逐笔循环带来的性能损失。 ## 2. 性能与向量化 ### 2.1 核心计算加速 回测与交易结果计算中的以下核心函数均使用 **Numba JIT**(`@njit(nogil=True, cache=True)`)加速: - **backtest_step**:单步内对整批标的计算买卖量、费用、持仓与交割更新。 - **calculate_trade_results**:交易结果与资金变动计算。 - **backtest_batch_steps**:在 Numba 内按时间步循环调用 `backtest_step`,完成整段回测。 - **backtest_flash_steps**:优化模式下使用,仅保留最终资金与持仓以节省内存,同样在 Numba 内完成批量步进。 信号混合(如多策略合并)在 `blender` 模块中部分算子也使用 `@njit` 加速。因此,回测主体是 **向量化 + Numba** 实现的,而非纯 Python 循环。 ### 2.2 时间维顺序与标的维向量化 | 维度 | 做法说明 | |----------|----------| | 时间维 | 顺序步进,以正确维护 T+1、交割周期、MOQ 等状态,与实盘一致。 | | 标的维 | 单步内对所有标的做数组运算(如 `op_signal`、`own_amounts` 等为 1D 数组),实现向量化。 | | 优化模式 | 多组参数通过多进程并行回测;每组内部使用 `backtest_flash_steps` 等高效路径,减少内存与计算。 | 首次运行或参数变化时,Numba 会编译相关函数,可能带来一次性的启动延迟;后续同类型回测会复用缓存,速度更快。 ### 2.3 与 VectorBT 的简要对比 | 对比项 | qteasy | VectorBT | |--------------|--------|----------| | 时间维 | 顺序步进,每步内向量化 | 全时间轴一次性矩阵运算,无显式时间循环 | | 状态与约束 | 显式维护 T+1、交割、MOQ 等,贴近实盘 | 多为简化资金曲线,不强调交割/MOQ | | 适用场景 | 需要正确模拟 A 股规则、多策略合并、精细成本与交割时 | 海量参数组合快速筛选、研究向回测 | qteasy 在保证**状态正确性与规则可配置**的前提下,通过时间维顺序 + 标的维向量化 + Numba 单步,兼顾速度;多组参数优化则通过多进程并行弥补“单次不能全矩阵广播”的差异。 ## 3. 本目录与相关文档 - 回测入口与配置:[1. 回测概览](1.%20overview.md)、[2. 如何运行回测](2.%20run_backtest.md)。 - 回测结果与评价:[3. 回测结果的结构](3.%20result_structure.md)、[5. 回测结果评价与分析](5.%20evaluate_and_analyze.md)。 - 架构与实现细节:[设计:回测引擎与性能](../design/07-backtest-engine-and-performance.md)、[设计:设计初衷与独特优势](../design/08-design-rationale-and-advantages.md)。